
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>SpringBoot整合JPA - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>SpringBoot整合JPA - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是JPA（Java Persistence API）？它的核心目标和技术是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JPA是Sun官方提出的Java持久化规范，其全称为Java持久化API。它的核心目标是帮助开发者提高开发效率，尽量少写甚至不写SQL。其核心技术是JPQL（Java持久化查询语句），这是一种类似SQL但操作实体对象的查询语言。</div>
          </div>
          <div class="card-source">来源: JPA介绍</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">文档中提到了使用JPA可能带来哪些复杂性或潜在问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JPA通过注解来处理实体间的关联关系（如一对多），这会增加实体的复杂度，使其掺杂逻辑。在复杂的业务场景中，这容易导致实体间直接或间接的循环引用。此外，一些注解（如外键注解）如果使用默认设置，会直接影响数据库层面，例如在表上创建真实的外键。</div>
          </div>
          <div class="card-source">来源: JPA介绍</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在Spring Boot的YML配置中，`spring.jpa.hibernate.ddl-auto=update` 这项配置起什么作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这是一个关键配置，它的作用是让JPA的实现（如Hibernate）根据应用程序中的实体类定义来自动更新数据库的表结构。这意味着当实体类发生变化时，对应的数据库表会自动进行调整。</div>
          </div>
          <div class="card-source">来源: 环境搭建</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请描述一下文档中提到的JPA Repository接口的继承体系。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这个体系从顶层的空接口 `Repository` 开始，它是一个标识接口。它的子接口 `CrudRepository` 提供了基础的CRUD功能。`CrudRepository` 的子接口 `PagingAndSortingRepository` 在其基础上增加了分页和排序的功能。而 `JpaRepository` 则是 `PagingAndSortingRepository` 的子接口，增加了批量操作等更实用的功能。</div>
          </div>
          <div class="card-source">来源: Repository 的子接口</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">在JPA Repository中定义查询方法时，需要遵循怎样的命名规范？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">查询方法的定义需要符合特定规范。方法名通常以 `find`、`read` 或 `get` 开头（例如 `findBy`、`readBy`、`getBy`）。在涉及条件查询时，条件的属性通过关键字连接，并且属性的首字母需要大写。</div>
          </div>
          <div class="card-source">来源: Repository类中方法定义的规范</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当实体类中可能存在属性名冲突时（例如同时存在`userAddress`属性和`user.address`的级联属性），JPA如何处理？如何显式指定使用级联属性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">如果存在属性名冲突，JPA会优先使用当前类的属性，而不是级联属性。如果需要明确指定使用级联属性进行查询，应该在方法名中用下划线 `_` 来连接属性，例如 `findByUser_Address_Zip()`。</div>
          </div>
          <div class="card-source">来源: Repository类中方法定义的规范</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在使用`@Query`注解执行UPDATE或DELETE操作时，为什么必须同时使用`@Modifying`注解？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为`@Query`中编写更新语句时，需要通过`@Modifying`注解来通知Spring Data JPA这是一个更新操作。默认情况下，Spring Data JPA为每个方法添加的事务是只读事务，无法完成更新操作，`@Modifying`注解会确保使用一个可以执行写入操作的事务。</div>
          </div>
          <div class="card-source">来源: JPQL</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在JPQL查询中，向`@Query`注解传递参数的两种主要方式是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">有两种主要方式：1. 按顺序传递参数，使用 `?` 后面跟上参数的序号（例如 `?1`, `?2`）。2. 按名称传递参数，在查询语句中使用冒号 `:` 后跟参数名（例如 `:id`, `:name`），并在方法参数前使用 `@Param` 注解指定名称。</div>
          </div>
          <div class="card-source">来源: JPQL</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">`JpaSpecificationExecutor`接口的作用是什么？它与`JpaRepository`等接口是什么关系？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`JpaSpecificationExecutor`接口用于执行复杂的动态查询（JPA Criteria查询）。它不属于`Repository` -> `CrudRepository` -> `JpaRepository`这个主要的继承体系，是一个独立的接口，需要在使用它的Repository中单独继承。</div>
          </div>
          <div class="card-source">来源: JpaSpecificationExecutor</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
